class_name DurationEffectComponent
extends GameplayEffectComponent

## 效果已持续时间
var elapsed_time: float = 0.0

var _duration_ended: bool = false

var _duration_reset: bool = false


func _on_attach(_source: Variant) -> void:
	parent.target.tag_manager.add_tags(component_asset.granted_tags)
	parent.target.ability_manager.grant_abilities(component_asset.granted_abilities)

	if component_asset.duration_refresh_policy == DurationEffectComponentAsset.DurationRefreshPolicy.AfterBeingAttached:
		elapsed_time = 0.0


func _on_update(delta: float) -> void:
	elapsed_time += delta

	if component_asset.duration != 0.0 and elapsed_time >= component_asset.duration:
		_duration_ended = true
		parent.on_duration_end()


func _on_periodic_tick() -> void:
	pass


func _on_duration_end() -> void:
	if _duration_reset:
		_duration_reset = false
	else:
		parent.expired = true


func _on_stack_update(_variation: int) -> void:
	if component_asset.duration_refresh_policy == DurationEffectComponentAsset.DurationRefreshPolicy.StackUpdated:
		# 给堆叠更新策略的持续时间结束临时打的补丁：
		# 先是 duration_effect_component 调用 on_duration_end，
		# 然后 stack_effect_component 调用 on_stack_update，
		# 最后 duration_effect_component 调用 _on_duration_end，
		# 这个顺序只能提前把 _on_duration_end 中的 parent.expired 锁住。
		if _duration_ended:
			_duration_ended = true
			_duration_reset = true
		elapsed_time = 0.0


func _on_detach(_source: Variant) -> void:
	parent.target.ability_manager.remove_abilities(component_asset.granted_abilities)
	parent.target.tag_manager.remove_tags(component_asset.granted_tags)
